package com.ctg.itrdc.sysmgr.portal.control;

import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import javax.validation.Valid;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.ctg.itrdc.pasp.core.Entity;
import com.ctg.itrdc.pasp.core.IBaseService;
import com.ctg.itrdc.pasp.core.PageInfo;
import com.ctg.itrdc.sysmgr.portal.api.dto.BaseDTO;
import com.ctg.itrdc.sysmgr.portal.api.dto.SystemPostRoleDTO;
import com.ctg.itrdc.sysmgr.portal.api.dto.SystemUserPostDTO;
import com.ctg.itrdc.sysmgr.portal.api.dto.SystemUserRoleDTO;
import com.ctg.itrdc.sysmgr.portal.common.constant.DictEnum;
import com.ctg.itrdc.sysmgr.portal.common.entity.CommonResult;
import com.ctg.itrdc.sysmgr.portal.exception.SysmgrContrlException;
import com.ctg.itrdc.sysmgr.portal.service.exception.SysmgrServiceException;
import com.ctg.itrdc.sysmgr.portal.service.utils.BeanUtils;
import com.ctg.itrdc.sysmgr.portal.service.utils.excel.ExcelToBean;
import com.ctg.itrdc.sysmgr.portal.utils.DTOHelper;
import com.google.common.collect.Lists;

public abstract class SysmgrCURDController<ID extends Serializable, T extends BaseDTO>{

	@Autowired
	private IBaseService<? extends Entity<ID>, ID, T> baseService;

	@RequestMapping("/insert")
	@ResponseBody
	public CommonResult insert(@Valid T dto ,BindingResult result) throws Exception {
		DTOHelper.valid(result);
		DTOHelper.updateDTO(dto);
		ID i = baseService.insert(dto);
		return new CommonResult(HttpStatus.OK.toString(), "新增数据成功",i);
	}

	@RequestMapping("/update")
	@ResponseBody
	public CommonResult updateByPrimaryKey(@Valid T dto,BindingResult result) throws Exception {
		DTOHelper.valid(result);
		DTOHelper.updateDTO(dto);
		int i = baseService.updateByPrimaryKey(dto);
		return new CommonResult(HttpStatus.OK.toString(), "更新数据成功",i);
	}

	@RequestMapping("/get")
	@ResponseBody
	public CommonResult selectByPrimaryKey(T dto) throws Exception {
		String id = BeanUtils.getProperty(dto, "id");
		T result = (T) baseService.selectByPrimaryKey(dto);
		return new CommonResult(HttpStatus.OK.toString(), "查询数据成功", result);
	}

	@RequestMapping("/query")
	@ResponseBody
	public CommonResult selectByExample(T dto) throws Exception {
		List<T> result = baseService.selectByExample(dto);
		return new CommonResult(HttpStatus.OK.toString(), "查询数据成功", result);
	}

	@RequestMapping("/page")
	@ResponseBody
	public CommonResult queryPageInfo(T dto,
			@RequestParam(defaultValue = "0") Integer currentPage,
			@RequestParam(defaultValue = "10") Integer perPage)
			throws Exception {
		PageInfo<T> pageInfo = baseService.queryPageInfo(dto,
				currentPage, perPage);
		return new CommonResult(HttpStatus.OK.toString(), "分页查询成功", pageInfo);
	}

	@RequestMapping("/delete")
	@ResponseBody
	public CommonResult deleteByPrimaryKey(T dto) throws Exception {
		int i = baseService.deleteByPrimaryKey(dto);
		return new CommonResult(HttpStatus.OK.toString(), "删除成功",i);
	}

	/**
	 * 批量删除，不推荐使用
	 * 
	 * @param ids
	 * @param dto
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("/batch/delete")
	@ResponseBody
	public CommonResult batchDeleteByPrimaryKey(@RequestParam String ids, T dto)
			throws Exception {
		List<T> dtoList = Lists.newArrayList();
		String[] idStr = ids.split(",");
		Class<? extends BaseDTO> clz = dto.getClass();
		Method method = null;
		try {
			method = clz.getMethod("setId", Long.class);
			for (String id : idStr) {
				Long idNum = Long.parseLong(id);
				T tmp = (T) clz.newInstance();
				method.invoke(tmp, idNum);
				dtoList.add(tmp);
			}
		} catch (NoSuchMethodException e1) {
			method = clz.getMethod("setId", Integer.class);
			for (String id : idStr) {
				Integer idNum = Integer.parseInt(id);
				T tmp = (T) clz.newInstance();
				method.invoke(tmp, idNum);
				dtoList.add(tmp);
			}
		}

		// 批量删除
		baseService.batchDeleteByPrimaryKey(dtoList);
		
		return new CommonResult(HttpStatus.OK.toString(), "删除成功");
	}

	@RequestMapping(value = "/excel2db", method = RequestMethod.POST)
	@ResponseBody
	public CommonResult excel2Db(@RequestParam MultipartFile[] excel, T dto)
			throws Exception {
		for (MultipartFile multipartFile : excel) {
			InputStream is = multipartFile.getInputStream();
			List<T> dtoList = new ExcelToBean().readFromInputStream(null, is,
					dto.getClass());
			for (T tmp : dtoList) {
				DTOHelper.updateDTO(tmp);
			}
			// 批量插入
			baseService.batchInsert(dtoList);
		}
		return new CommonResult(HttpStatus.OK.toString(), "猴犀利耶，成功了~");
	}
	
	@RequestMapping(value = "/exist")
	@ResponseBody
	public CommonResult exist(T dto){
		Boolean exist = baseService.exists(dto);
		String msg = "存在";
		if(!exist){
			msg = "不存在";
		}
		return new CommonResult(HttpStatus.OK.toString(),msg,exist);
	}
	
	@RequestMapping("/batch/one2ManyInsert")
	@ResponseBody
	public CommonResult one2ManyBatchInsert(
			@RequestParam(required=false) String ids, // id列表
			@RequestParam(required=false) String idField, // ids设置的字段
			@Valid T dto,BindingResult result){
		
		if(StringUtils.isBlank(ids)){
			throw new SysmgrContrlException("id列表不能为空~");
		}
		DTOHelper.valid(result);
		DTOHelper.updateDTO(dto);
		
		one2ManybatchInsert(ids,idField,dto);
		return new CommonResult(HttpStatus.OK.toString(),"批量新增成功");
	}

	private void one2ManybatchInsert(String ids,String idField, T dto) {
		List<T> dtoList = Lists.newArrayList();
		String[] arr = ids.split(",");
		if(StringUtils.isBlank(idField)){
			if(dto instanceof SystemUserPostDTO){
				((SystemUserPostDTO)dto).setStatusCd(DictEnum.StatusCd.S0A.toString());
				idField = "sysPostId";
			}else if(dto instanceof SystemUserRoleDTO){
				((SystemUserRoleDTO)dto).setStatusCd(DictEnum.StatusCd.S0A.toString());
				idField = "sysRoleId";
			}else if(dto instanceof SystemPostRoleDTO){
				((SystemPostRoleDTO)dto).setStatusCd(DictEnum.StatusCd.S0A.toString());
				idField = "sysRoleId";
			}
		}
		for (String obj : arr) {
			Long id = Long.parseLong(obj);
			T tmp = (T) BeanUtils.applyIfNotException(dto,dto.getClass());
			try {
				if(id!=null)
					BeanUtils.setProperty(tmp, idField, id);
			} catch (IllegalAccessException | InvocationTargetException e) {
				//e.printStackTrace();
				throw new SysmgrServiceException(e.getMessage());
			}
			if(!baseService.exists(tmp))
				dtoList.add(tmp);
		}
		if(CollectionUtils.isNotEmpty(dtoList))
			baseService.batchInsert(dtoList);
	}
}
